﻿using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using NExplorer.Properties;

namespace NExplorer.Controls
{
	internal class ExplorerTreeView : TreeView
	{
		private readonly ExplorerService	_explorerService;
		private readonly ImageList			_imageList;
		
		public ExplorerTreeView()
		{
		    DoubleBuffered = true;

			ImageList = _imageList = new ImageList()
			{
				ImageSize = new Size(16, 16),
				ColorDepth = ColorDepth.Depth32Bit
			};

			_imageList.Images.Add(Resources.Computer);

			_explorerService = (ExplorerService)ServiceManager.Explorer;
		}

        protected override void OnHandleCreated(EventArgs e)
        {
            base.OnHandleCreated(e);
            DoubleBuffered = true;
            Utilities.SetExplorerStyle(this);
        }

		protected override void InitLayout()
		{
			base.InitLayout();

			if (!DesignMode)
			{
				_explorerService.CurrentDirectoryChanged += WhenCurrentDirectoryChanged;

			    bool firstExpanded = false;

				foreach (string drive in Environment.GetLogicalDrives())
                {
					DriveInfo driveInfo = new DriveInfo(drive);
					string label;
                	
					if (driveInfo.IsReady)
					{
						label = string.IsNullOrEmpty(driveInfo.VolumeLabel) ? "Local Disk" : driveInfo.VolumeLabel;
					}
					else
					{
						label = "Local Drive";
					}

					string text = string.Format("{0} ({1})", label, driveInfo.RootDirectory);
					DirectoryTreeNode node = new DirectoryTreeNode(driveInfo.RootDirectory, text);
                    Nodes.Add(node);
                    node.Initialize();

                    if (!firstExpanded)
                    {
                        node.Expand();
                        firstExpanded = true;
                    }
                }
			}
		}

		private void WhenCurrentDirectoryChanged(object sender, EventArgs e)
		{
			DirectoryInfo directory = ServiceManager.Explorer.CurrentDirectory;

			// Make sure this directory isn't already selected so we don't waste our time finding 
			// an already-selected node.
			DirectoryTreeNode node = SelectedNode as DirectoryTreeNode;

			if (node == null || node.DirectoryInfo != directory)
			{
				// Find the drive treenode
				foreach (DirectoryTreeNode driveNode in Nodes)
				{
					if (driveNode.DirectoryInfo.IsEqualTo(directory.Root))
					{
						// Found the drive, now we have to drill down into the correct tree node.
						// Convert to lowercase before splitting to lessen the number of conversions required.
						string[] path = directory.FullName.ToLower().Split('\\');
						path = path.RemoveEmptyElements();
						DirectoryTreeNode dirNode = driveNode;

						if (path.Length > 1)
						{
							for (int i = 1; i < path.Length; i++)
							{
								dirNode = dirNode.GetChildNode(new LowerCaseString(path[i]), true);

								if (dirNode == null)
								{
									break;
								}
							}
						}

						SelectedNode = dirNode;

						break;
					}
				}
			}
		}

		protected override void OnBeforeExpand(TreeViewCancelEventArgs e)
		{
			base.OnBeforeExpand(e);

			DirectoryTreeNode directoryTreeNode = e.Node as DirectoryTreeNode;

			if (directoryTreeNode != null)
			{
				directoryTreeNode.PrepareForExpand();
			}
		}

		protected override void OnAfterSelect(TreeViewEventArgs e)
		{
			base.OnAfterSelect(e);

			if (e.Action != TreeViewAction.Unknown)
			{
				_explorerService.NavigateTo(((DirectoryTreeNode)e.Node).DirectoryInfo);
			}
		}

        //protected override void OnMouseUp(MouseEventArgs e)
        //{
        //    base.OnMouseUp(e);

        //    DirectoryTreeNode node = GetNodeAt(e.Location) as DirectoryTreeNode;

        //    if (node != null)
        //    {
        //        if (e.Button == MouseButtons.Right)
        //        {
        //            ContextMenuStrip menu = _explorerService.CreateContextMenu();
        //            menu.Show(this, e.Location);
        //        }
        //    }
        //}
	}
}